BroadcastTo ================= 将输入张量按 NumPy / MindSpore 广播规则扩展到目标形状 ``output_shape``。 输入维数可少于输出维数(左侧隐式补 1);每一维上,输入长度必须为 1(可广播)或与输出长度相等。 形状维数不超过 8。 设输出维数为 :math:`M`,输入维数为 :math:`K`,且满足 :math:`K \le M`。先将输入形状左侧补 1, 得到对齐后的输入形状 :math:`\tilde{I}`: .. math:: \tilde{I}_i = \begin{cases} 1, & 0 \le i < M - K \\ I_{i - (M - K)}, & M - K \le i < M \end{cases} 对每个维度 :math:`i`,要求 :math:`\tilde{I}_i = 1` 或 :math:`\tilde{I}_i = O_i`, 其中 :math:`O` 为输出形状。 **索引映射** 对输出线性下标 :math:`idx`,将其按输出 stride 分解为多维坐标 :math:`(p_0,\ldots,p_{M-1})`, 再映射到输入偏移: .. math:: \begin{aligned} S^{out}_{M-1} &= 1,\quad S^{out}_{i} = S^{out}_{i+1} \cdot O_{i+1} \\ S^{in}_{M-1} &= \begin{cases} 0, & \tilde{I}_{M-1} = 1 \\ 1, & \text{otherwise} \end{cases},\quad S^{in}_{i} = \begin{cases} 0, & \tilde{I}_{i} = 1 \\ S^{in}_{i+1} \cdot \tilde{I}_{i+1}, & \text{otherwise} \end{cases} \\ \mathrm{in\_off} &= \sum_{i=0}^{M-1} p_i \cdot S^{in}_{i} \end{aligned} 即 :math:`O[idx] = I[\mathrm{in\_off}]`。当某维 :math:`\tilde{I}_i = 1` 时, 该维 stride 为 0,对应元素沿该维重复。 输入: - **input** - 输入数据地址 - **input_shape** - 输入形状数组 - **input_shape_size** - 输入形状维数 :math:`K` - **output_shape** - 目标输出形状数组 - **output_shape_size** - 输出形状维数 :math:`M` - **core_mask** - 核掩码(仅共享存储版本使用) 输出: - **output** - 输出数据地址 支持平台: ``FT78NE`` ``MT7004`` .. note:: - FT78NE 支持 int8, int16, int32, fp32, fp64, cplx64, cplx128 - MT7004 支持 int16, int32, fp16, fp32, cplx64 **共享存储版本:** .. c:function:: void i8_broadcast_to_s(int8_t *input, int8_t *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) .. c:function:: void i16_broadcast_to_s(int16_t *input, int16_t *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) .. c:function:: void i32_broadcast_to_s(int *input, int *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) .. c:function:: void hp_broadcast_to_s(float16 *input, float16 *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) .. c:function:: void fp_broadcast_to_s(float *input, float *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) .. c:function:: void dp_broadcast_to_s(double *input, double *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) .. c:function:: void c64_broadcast_to_s(float *input, float *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) .. c:function:: void c128_broadcast_to_s(double *input, double *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size, int core_mask) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 12 // MT7004 示例(共享存储多核,DDR 地址) // 例:input {1,N} -> output {N,N} void TestBroadcastToSMCFp32(int n, int core_mask) { int core_id = get_core_id(); int logic_core_id = GetLogicCoreId(core_mask, core_id); int core_num = GetCoreNum(core_mask); float *input = (float *)0x81000000; float *output = (float *)0x82000000; int input_shape[2] = {1, n}; int output_shape[2] = {n, n}; sys_bar(0, core_num); fp_broadcast_to_s(input, output, input_shape, 2, output_shape, 2, core_mask); } void main() { int core_mask = 0b1111; TestBroadcastToSMCFp32(32, core_mask); } **私有存储版本:** .. c:function:: void i8_broadcast_to_p(int8_t *input, int8_t *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) .. c:function:: void i16_broadcast_to_p(int16_t *input, int16_t *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) .. c:function:: void i32_broadcast_to_p(int *input, int *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) .. c:function:: void hp_broadcast_to_p(float16 *input, float16 *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) .. c:function:: void fp_broadcast_to_p(float *input, float *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) .. c:function:: void dp_broadcast_to_p(double *input, double *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) .. c:function:: void c64_broadcast_to_p(float *input, float *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) .. c:function:: void c128_broadcast_to_p(double *input, double *output, int *input_shape, int input_shape_size, int *output_shape, int output_shape_size) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 7 // MT7004 示例(私有存储单核,AM 地址) void TestBroadcastToAMFp32(int n) { float *input = (float *)0x10000000; float *output = (float *)0x10020000; int input_shape[2] = {1, n}; int output_shape[2] = {n, n}; fp_broadcast_to_p(input, output, input_shape, 2, output_shape, 2); } void main() { TestBroadcastToAMFp32(32); }